Using Weave
Weave is an application for creating
HTML files out of Weave scripts. Doubleclick !Weave to put its icon
on the iconbar. A Weave script must be a text file with a name ending
in
/wve
. Drag a Weave script onto the Weave iconbar-icon
and !Weave will attempt to convert it into an HTML file. If it cannot,
a taskwindow will display an error message. If it can it will produce
an HTML output file in the same directory as the Weave script with
the name got by substituting the suffix /html for /wve (unless the
FILE
attribute is set in the script - see the
manual
).
The new name will displayed in a confirmatory taskwindow
(unless the
QUIET
attribute is set to
true
in the script - see the
manual
). Clicking Select
on the iconbar icon will open this help document. Clicking Adjust
will open the directory !Weave.lib which contains libraries
of Weave code.
This document is intended to show how to use !Weave and not how to
write Weave scripts. Nevertheless here is a very brief introduction.
Possibly the simplest Weave script contains the single line:
=> "Hello World"The symbol => shows the value, here a string, that is to be loaded by !Weave. Try it, then look at its output in a browser. Try omitting the => or a doublequote and note the error messages. Here is another script that produces the same output:
local x = "Hello "
=> { x; "World"; }
The word
local
introduces a
local variable
. The returned value is given by an expression that is
a
list
of two items, the variable
x
and the string
World
each terminated by a semicolon
(commas can be used instead) inside braces. Variables are useful if
the same text is used many times. So a Weave script consists of
definitions (possibly none) followed by
a single
return statement
, introduced by the symbol
=>
(or the word
return
).
The value returned must be a
rope
.
A rope is either a string (possibly empty) or a list of ropes (possibly
empty). Strings can be enclosed in double quotes, as above, or single quotes, or
within double square brackets.
"doublequote string" 'singlequote string'
[[
this is also a string,
it can stretch over many lines
and it can contain either
sort of quote " '.]]
A newline immediately following an opening double square bracket
is ignored - convenient for layout purposes. Singlequotes can appear in
doublequote strings and doublequotes in singlequote strings.
You are spoiled for choice. In computer science
jargon, a rope is a tree whose leaves are strings; a string-with-holes is
a convenient mental picture.
If you know how to express strings and lists you have all of the tools
for describing ropes. When you use variables to stand for expressions
the definitions of the variables must precede their use.
You can use separate files for your definitions (see the word
require
in the manual). The keyword
local
means that the variable's scope is
local to file in which it is declared.
When should one use a variable instead of a literal expression? The rule
of thumb is: whenever an expression is used more than once. That is
because lookup of the value of a variable is much faster than evaluation
of a compound expression. So in practice there is no harm in using a
variable instead of a literal expression, but you should never need to use
the same compound expression twice. As a result of the fact that definitions
must precede their use, Weave scripts really need to be read backwards (as
Harriet Bazley pointed out in Archive in 2002).
A rope, a tree structure, is read by Weave into a datastructure in memory
very efficiently. Weave walks the tree outputting each leaf, a string, to
the output file in depth-first order. This means that strings
never need to be copied, concatenated or moved.
In addition to strings and sequences Weave provides a certain number of
built-in values that produce functions. For the full details of Weave syntax see the
manual
. Suppose you wanted to produce a tagged expression:
<cite class="bar"> some text </foo>
The rope to do this is given by the expression
TAG.cite (CLASS.bar) [[ some text ]]
So the expression
TAG.cite (CLASS.bar)
is a function from ropes to ropes.
TAG.foo
is a function from ropes (attributes) to functions from
ropes to ropes. The words
TAG
and
CLASS
are
pseudotables
. They must be suffixed by a
dot followed by a string that does not begin with a digit
but is composed of letters, digits or underscores. In the
case of TAG the suffix after the dot should be a valid HTML
tag. In the case of CLASS the suffix after the dot should
be a class defined in a CSS file. The functions
div, span, pre, p
are by Weave as abbreviations
for
TAG.div, TAG.span, TAG.pre , TAG.p
for conciseness, as these tags occur often. The
statement
local x, y, z in CLASS
is a more concise version of
local x, y, z = CLASS.x, CLASS.y, CLASS.z
or
local x = CLASS.x
local y = CLASS.y
local z = CLASS.z
Similar syntax applies to any pseudotable, such as MONOTAG
which is used for tags that have no matching end-tag. So
local hr, br in MONOTAG
defines variables wich are functions from ropes to ropes.
The expression
hr (STYLE [[display: none;]])
is a rope producing the HTML
<hr style="display: none;">
Note that STYLE is a function from strings to ropes, not
a pseudotable like CLASS.
Debugging can be painful. This code
=> { "a"; div "b" }
produced this:lw: weave:!RunImage:21: bad type function at 1.3.6.2.6 stack traceback: [C]: in function 'error' weave:!RunImage:21: in function 'walk' weave:!RunImage:17: in function 'walk' weave:!RunImage:17: in function 'walk' weave:!RunImage:17: in function 'walk' weave:!RunImage:17: in function 'walk' weave:!RunImage:17: in function 'walk' weave:!RunImage:31: in function 'WRITE' weave:!RunImage:136: in main chunk [C]: in ?The error is that div "b" is a function not a rope (not a string or a list). Hence the bad type message. The expression 1.3.6.2.6 indicates that the error occurred 6 levels down the tree (5 instances of weave:!RunImage:17) in the second item of the list. The correct code should have had div "" "b" . So omitting the attribute argument for a tag function produces a bad type error. Another common error is omitting a semicolon (or comma). This code
=> { "a" "b" }
produced this error:lw: weave:!RunImage:81: RAM::RamDisc0.$.T/wve:1: '}' expected near '"b"' stack traceback: [C]: in function 'assert' weave:!RunImage:81: in function 'DOFILE' weave:!RunImage:134: in main chunk [C]: in ?The first line indicates a syntax error in line 1. These errors are easier to find.